  #include "Parser.h"

//===========================================================================
//
//  Constructor
// 			Parameters: rq - pointer to the parsed packets queue queue
//
//
Parser::Parser(map<string,struct HTTP_SESSION> *sessTable)
:_httpSessionsTable(sessTable),_serverPort(0)
{
	_rk=new RabinKarp();
	_sch=_rk;
	init();

}
//===========================================================================
//
// Desctructor
//
Parser::~Parser(void)
{
	delete _rk;
}

//===========================================================================
//
// Init() - initialize the parser
//
void Parser::init()
{
	getServerPort();
	loadIgnoredExtensions();
}

//===========================================================================
//
// run(): the main parser method
//			pops packet from the parsed packets queue
//			search the http data for _signatures
//
void Parser::run()
{
	int endRequestIndex=0;
	int endReplyIndex=0;
	map<string,struct HTTP_SESSION>::iterator itr;

	while(1) // main loop
	{
		for(itr = _httpSessionsTable->begin(); itr != _httpSessionsTable->end(); ++itr)
		{
			// if the current session has no new data --> contiune to the next session
			if(itr->second.state.newData==false)
				continue;

			int session_data_size=itr->second.httpData.size();

			//travers over the session's http data array(vector)
 			for(int i=itr->second.state.dataArrayIndex;i<session_data_size;i++)
 			{
				if(itr->second.httpData[i].type==0) // request
				{
					//build HTTPRequest object
					HTTPRequest req(itr->second.httpData[i].data,itr->second.httpData[i].data.size());

					if( checkExtension(req.getUrlExtension()) )
						continue;

					int sig_index=-1;

					// Signature has been found
					if( (sig_index=searchRequest(itr->second.httpData[i].data))>=0 )
					{
						//cout<<itr->second.httpData[i].data<<endl;
						action(itr->second,i,sig_index);
					}
				}
			}//for

			//update the index of the session's http data array
			itr->second.state.dataArrayIndex=session_data_size;
			// new session's http data has been parsed -> set newData to false
			itr->second.state.newData=false;

		}// for(itr = _httpSessionsTable->begin();

	} //  main loop
}

//===========================================================================
//
// buildHttpRequest():
//
//
void Parser::buildHttpRequest(const string &request)
{

}

//===========================================================================
//
// buildHttpReply():
//
//
void Parser::buildHttpReply(const string &reply)
{
}


//===========================================================================
//
// searchRequest():
//				Parameters: request - the string to search the signature on
//
//				Return Value: the signature index in the signatures array,or
//							  -1 if signature not found
//
int Parser::searchRequest(const string& request)
{
	return (_rk->findSignatures(request));
}

//===========================================================================
//
// action():
//
//

void Parser::action(struct HTTP_SESSION& session,int attackReqIndex,int sig_index)
{
	reset(session);
}
//===========================================================================
//
// reset(): calls the sendTCPreset() function in order to send TCP reset
//			Parameters: sess - reference to the relevant http sessions in the sessions table
//
int Parser::reset(struct HTTP_SESSION &sess)
{
	#ifdef DEBUG
	cout<<"Sending TCP reset.."<<endl;
	cout<<"Attacker-> "<<sess.tcpParams.ip_src<<":"<<sess.tcpParams.src_port<<endl;
	#endif

	sendTCPpacket(sess.tcpParams.src_port,sess.tcpParams.dst_port,sess.tcpParams.ip_src.c_str(),sess.tcpParams.ip_dst.c_str(),sess.seqackParams.server_ack);
	sendTCPpacket(sess.tcpParams.dst_port,sess.tcpParams.src_port,sess.tcpParams.ip_dst.c_str(),sess.tcpParams.ip_src.c_str(),sess.seqackParams.client_ack);
	return 0;
}
//===========================================================================
//
// getServerPort()
//
void Parser::getServerPort()
{
	const string sniffer_conf_file="/opt/swaf/conf/sniffer.conf";
	try
	{
		ConfigFile cf(sniffer_conf_file);
	   _serverPort=(cf.Value("web-server","port"));
	}
	catch(...)
	{
	        cout <<"\nError --> Failed to read server port from "<<sniffer_conf_file<<endl;
			exit(1);
	}
}
//===========================================================================
//
// loadIgnoredExtensions()
//
void Parser::loadIgnoredExtensions()
{
	const string ignorefile="/opt/swaf/conf/ignore_list.txt";
	ifstream inFile;
	string extention;
	int index;
	try
	{
		inFile.open((ignorefile.c_str()));
		if (!inFile.is_open())
		{
			throw "Failed to open file!!!";
		}
		while (inFile >> extention)
		{
			_ignoreList.push_back(extention);
		}

		inFile.close();
	}
	catch(const char *e)
	{
	        cout <<"\nError --> "<<e<<endl;
			cout <<"Check file: "<<ignorefile<<"\n"<<endl;
			exit(1);
	}
}

//===========================================================================
//
// checkExtension() - returns true if extension is presence in the ignore extensions list (vector)
//					 Parameters: ext - reference to extension string
//
bool Parser::checkExtension(string &ext)
{
	for (vector<string>::iterator itr = _ignoreList.begin(); itr!=_ignoreList.end(); ++itr)
	{
		if( ((*itr).compare(ext))==0 )
			return true;
	}
	return false;
}



